import React, {
  forwardRef,
  ReactElement,
  useCallback,
  useContext,
  useEffect,
  useImperativeHandle,
  useMemo,
  useRef,
  useState
} from 'react';
import { View } from 'react-native';

import styles from './style';
import {
  RoundInfo,
  RoundInfoProblem
} from '../../../../api/class/getRoundList';
import {
  clearAllFinishProblemTimer,
  finishProblem,
  updateProblemTime
} from '../../actions';
import ProblemTimer from '../ProblemTimer';
import ClassRoomProblem from './components/ClassRoomProblem';
import { PPT } from '../../types';
import { Store } from '../../reducer';

const Problem = ({ problem, roundId }: PPT, ref: any): ReactElement => {
  const [isPrepare, setIsPrepare] = useState(false);
  const [isStart, setIsStart] = useState(false);
  const [localAnswerDuration, setAnswerDuration] = useState(0);
  const problemView = useRef<any>(null);
  const timer = useRef<any>(null);
  const isPause = useRef<boolean>(false);

  const { state } = useContext(Store);
  const { currentPPT } = state;
  const { round } = currentPPT;

  const { roundInfoProblem = {}, roundId: currentRoundId } =
    (round as RoundInfo) || {};
  const { haveSubmitAnswer, userAnswer } =
    (roundInfoProblem as RoundInfoProblem) || {};

  useEffect((): void => {
    if (currentRoundId !== roundId) return;
    if (isStart) {
      if (problemView && problemView.current) {
        problemView.current.update(haveSubmitAnswer, userAnswer);
      }
    } else {
      setAnswerDuration(0);
    }
  }, [currentRoundId, haveSubmitAnswer, isStart, roundId, userAnswer]);

  const prepare = (): Promise<void> =>
    new Promise((resolve): void => {
      setIsPrepare(true);
      resolve();
    });

  const seek = (time: number): Promise<void> =>
    new Promise((resolve): void => {
      resolve();
    });

  const pause = (): Promise<void> =>
    new Promise((resolve): void => {
      isPause.current = true;
      if (timer && timer.current) {
        timer.current.pause();
      }
      resolve();
    });

  const play = async (): Promise<void> =>
    new Promise((resolve): void => {
      isPause.current = false;
      if (timer && timer.current) {
        timer.current.start();
      }
      resolve();
    });

  const start = (r: RoundInfo): Promise<void> =>
    new Promise((resolve): void => {
      let duration = 0;
      if (r && r.roundInfoProblem) {
        const {
          answerDurationAfterDiscuss,
          answerDuration
        } = r.roundInfoProblem;
        duration = answerDurationAfterDiscuss || answerDuration || 0;
      }
      if (!isPrepare) {
        prepare();
      }
      setAnswerDuration(duration);
      setIsStart(true);
      play();
      resolve();
    });

  const destroy = (): Promise<void> =>
    new Promise((resolve): void => {
      setIsPrepare(false);
      setIsStart(false);
      isPause.current = false;
      resolve();
    });

  const mute = (): void => {};

  useImperativeHandle(ref, (): { [key: string]: any } => {
    return {
      prepare,
      start,
      pause,
      seek,
      destroy,
      play,
      mute
    };
  });

  const onEnd = useCallback((): void => {
    if (isPause.current) return;
    clearAllFinishProblemTimer();
    finishProblem(true);
  }, []);

  return useMemo(
    (): ReactElement => (
      <View style={styles.container}>
        <View style={styles.content}>
          {isPrepare && problem && (
            <ClassRoomProblem
              ref={problemView}
              roundId={roundId}
              problem={problem}
            />
          )}
          {isStart && (
            <ProblemTimer
              ref={timer}
              key={`doProblem-${roundId}`}
              title="答题倒计时"
              action={onEnd}
              time={localAnswerDuration}
              updateTime={updateProblemTime}
            />
          )}
        </View>
      </View>
    ),
    [isPrepare, isStart, localAnswerDuration, onEnd, problem, roundId]
  );
};

export default forwardRef(Problem);
